import { AppDataSource } from '../config/database';
import { AuthorizationCode } from '../entity/AuthorizationCode';
import { AccessToken } from '../entity/Accesstoken';
import { BrandStrategy } from '../brand/strategyFactory';
import * as path from 'path';
import * as fs from 'fs';
import axios from "axios";
import { In } from 'typeorm/find-options/operator/In';

const brandConfigPath = path.resolve(__dirname, '../../brand-config.json');
const BrandConfig = JSON.parse(fs.readFileSync(brandConfigPath, 'utf-8'));

export class MockThirdParty implements BrandStrategy {
  protected appId: string;
  protected appSecret: string;
  protected intervalId: NodeJS.Timeout | null = null;

  constructor(appId: string, appSecret: string) {
    this.appId = appId;
    this.appSecret = appSecret;
  }

  // 模拟绑定操作
  async exchangeToken(code: string): Promise<{ access_token: string; expires_in: number }> {
    const config = BrandConfig[this.appId];
    if (!config || config.app_secret !== this.appSecret) {
      throw new Error('Invalid app credentials');
    }

    const codeRepo = AppDataSource.getRepository(AuthorizationCode);
    const tokenRepo = AppDataSource.getRepository(AccessToken);

    const authCode = await codeRepo.findOne({where: {code}, relations: ['user']});
    if (!authCode || Date.now() - authCode.createdAt.getTime() > 600_000) {
      throw new Error('Invalid or expired authorization code');
    }

    const token = Math.random().toString(36).substr(2, 16);
    await tokenRepo.save({
      userId: authCode.userId,
      appId: this.appId,
      token,
      expiresAt: new Date(Date.now() + 3600_000 * 24)
    });

    return {
      access_token: token,
      expires_in: 24
    };
  }

  // 实现 refreshToken 方法
  async refreshToken(userId: string, oldToken: string): Promise<{ access_token: string; expires_in: number }> {
    const tokenRepo = AppDataSource.getRepository(AccessToken);

    // 验证旧令牌是否有效
    const existingToken = await tokenRepo.findOne({
      where: {userId, token: oldToken, appId: this.appId}
    });

    if (!existingToken || existingToken.expiresAt < new Date()) {
      throw new Error('Invalid or expired token');
    }

    // 生成新令牌
    const newToken = Math.random().toString(36).substr(2, 16);
    await tokenRepo.save({
      userId,
      appId: this.appId,
      token: newToken,
      expiresAt: new Date(Date.now() + 3600_000 * 24) // 24小时有效期
    });

    // 返回新令牌
    return {
      access_token: newToken,
      expires_in: 24
    };
  }

  // 模拟解绑流程
  async revokeToken(token: string): Promise<boolean> { // 修改返回类型
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const result = await tokenRepo.delete({token, appId: this.appId});

    // 返回操作结果（受影响行数 > 0 表示成功）
    return result.affected !== 0;
  }

  // 模拟刷新token流程
  async generateAuthorizationCode(userId: string): Promise<{code: string, createdAt:Date}> {
    const codeRepo = AppDataSource.getRepository(AuthorizationCode);
    const code = Math.random().toString(36).substr(2, 8).toUpperCase();
    const createdAt =  new Date();
    await codeRepo.save({userId, code, createdAt});
    return { code, createdAt};
  }

// 获取品牌设备信息
  async getDeviceList(accessToken: string): Promise<{ did: string; name: string; type: string; online: boolean}[]> {
    // 验证accessToken
    const tokenRepo = AppDataSource.getRepository(AccessToken);
    const tokenRecord = await tokenRepo.findOne({
      where: {token: accessToken, appId: this.appId}
    });

    if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
      throw new Error('Invalid or expired access token');
    }

    // 获取品牌名
    const config = BrandConfig[this.appId];
    if (!config) {
      throw new Error('Invalid app configuration');
    }
    const brand = config.app_id;

    try {
      let response;
      if (brand === 'xiaomi') {
        // 调用小米设备API
        response = await axios.get('http://localhost:3000/xiaomi/devices', {
          headers: {
            'access_token': accessToken,
            'app_id': this.appId
          }
        });

        // 转换小米设备格式
        return response.data.data.devices.map((device: any) => ({
          did: device.did,
          name: device.name,
          type: device.type
        }));

      } else if (brand === 'midea') {
        // 调用美的设备API
        response = await axios.get('http://localhost:3000/midea/devices', {
          headers: {
            'Authorization': `Bearer ${accessToken}`,
            'ClientId': this.appId
          }
        });

        // 转换美的设备格式
        return response.data.data.applianceList.map((device: any) => ({
          did: device.virtualId,
          name: device.name,
          type: device.type
        }));
      } else {
        throw new Error(`Unsupported brand: ${brand}`);
      }
    } catch (error: any) {
      if (error.response) {
        // API返回的错误
        throw new Error(`API Error: ${error.response.data.message || error.response.statusText}`);
      } else if (error.request) {
        // 请求已发出但没有响应
        throw new Error('No response from device API');
      } else {
        // 其他错误
        throw new Error(`Device API request failed: ${error.message}`);
      }
    }
  }

  // 定时更新方法(只更新小米传感器设备)
  protected startDeviceStatusUpdater(
    generateStatusFn: (deviceId: string) => Record<string, any>,
    pushStatusFn: (deviceId: string, userId: string, status: Record<string, any>) => Promise<void>,
    deviceRepo: any
  ): void {
    // 先清除已有的定时器
    if (this.intervalId) {
      clearInterval(this.intervalId);
    }

    // 设置新的定时器，每5分钟执行一次
    this.intervalId = setInterval(async () => {
    try {
      console.log('开始定时更新传感器设备状态...');

      // 只查询已订阅的小米温湿度计和空气质量检测仪
      const subscribedDevices = await deviceRepo.find({
        where: {
          subscribed: true,
          type: In(['mi_temp_hum_sensor', 'mi_air_sensor']) // 只查询这两种设备类型
        }
      });

      // 记录找到的设备数量
      console.log(`找到 ${subscribedDevices.length} 个需要更新的传感器设备`);

      // 获取所有控制设备状态
      const controlDevices = await deviceRepo.find({
        where: {
          type: In(['mi_ac', 'midea_ac', 'mi_humidifier', 'mi_dehumidifier'])
        }
      });

      for (const device of subscribedDevices) {
        try {
          let newStatus = generateStatusFn(device.did);

          // 查找关联的控制设备
          const relatedControls = controlDevices.filter((control: { gid: any; }) => {
            // 同一分组或未分组
            return control.gid === device.gid || !control.gid;
          });

          // 应用锁定逻辑
          relatedControls.forEach((control: { type: string | string[]; status: { target_temperature: any; target_humidity: any; }; }) => {
            if (control.type.includes('ac') && control.status?.target_temperature) {
              newStatus.temperature = control.status.target_temperature;
            }
            if (control.type.includes('humidifier') && control.status?.target_humidity) {
              newStatus.humidity = control.status.target_humidity;
            }
          });

          device.status = newStatus;
          await deviceRepo.save(device);
          await pushStatusFn(device.did, device.userId, newStatus);

        } catch (deviceErr) {
          console.error(`处理设备 ${device.did} 时出错:`, deviceErr);
        }
      }
    } catch (err) {
      console.error('定时更新传感器设备状态失败:', err);
    }
  }, 5 * 60 * 1000); // 每5分钟执行一次

    console.log('传感器设备状态定时更新器已启动');
  }

  protected stopDeviceStatusUpdater(): void {
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
      console.log('设备状态定时更新器已停止');
    }
  }

}
